package com.api.shop.service.impl;

import com.api.shop.bean.ApiMessage;
import com.api.shop.bean.ApiParam;
import com.api.shop.bean.SysUser;
import com.api.shop.common.ApiStatusEnum;
import com.api.shop.common.RequestHolder;
import com.api.shop.common.ReturnData;
import com.api.shop.dao.ApiDao;
import com.api.shop.exception.MyDataException;
import com.api.shop.exception.ParamException;
import com.api.shop.service.GeneralUserService;
import com.api.shop.util.BeanValidator;
import com.api.shop.util.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: wyx
 * @Date: 2019-04-04 16:38
 * @Description: 普通用户 Service
 */
@Service
@Slf4j
public class GeneralUserServiceImpl implements GeneralUserService {

    @Resource
    private ApiDao apiDao;
    @Resource
    private RedisUtil redisUtil;

    @Override
    @Transactional
    public ReturnData addAPI(ApiMessage apiMessage, ArrayList<ApiParam> apiParamList, HttpServletRequest request) {
        SysUser sysUser = RequestHolder.getCurrentUser();
        if(sysUser == null){
            throw new MyDataException("用户信息不存在");
        }

        apiMessage.setApiBelongUserId(sysUser.getUserId());
        apiMessage.setApiStatus(ApiStatusEnum.CHECK_PENDING.getValue());
        //判断是否存在相同url的api
        Object object1 = redisUtil.getHash("api","userId_"+sysUser.getUserId());
        if(object1 != null) {
            ArrayList<String> urlArray = (ArrayList<String>) ((ArrayList<ApiMessage>) (object1)).stream().map(e -> e.getApiUrl()).collect(Collectors.toList());
            System.out.println("----------->输出urlArray from redis");
            for (String url : urlArray) {

                System.out.println(url);
            }
            if (urlArray.contains(apiMessage.getApiUrl())) {

                throw new ParamException("已存在相同url的Api");
            }
        }
        else{
            System.out.println("----> select from database");
            ArrayList<ApiMessage> apiMessageArrayList = apiDao.selectAllApiMessage();
            ArrayList<String> urlArray = (ArrayList<String>)apiMessageArrayList.stream().map(e -> e.getApiUrl()).collect(Collectors.toList());
            if(urlArray.contains(apiMessage.getApiUrl())){

                throw new ParamException("已存在相同url的Api");
            }
        }
        BeanValidator.check(apiMessage);
        BeanValidator.validateList(apiParamList);

        apiDao.insertMessage(apiMessage);
        log.info("Insert message {} success", apiMessage.getApiId());

        if(!(apiParamList == null || apiParamList.isEmpty())){
            apiDao.insertParam(apiParamList, apiMessage.getApiId());
            log.info("Insert params success");

            for(ApiParam param : apiParamList){
                param.setApiId(apiMessage.getApiId());
            }
            apiMessage.setApiParamArrayList(apiParamList);
        }

        Object object = redisUtil.getHash("api", "apiUserId_" + sysUser.getUserId());
        ArrayList<ApiMessage> apiMessageList;

        if(object != null){
            apiMessageList = (ArrayList)object;

            for(ApiMessage message : apiMessageList){
                log.info("---> " + message);
            }

        }else{
            log.info("===> addAPI: getHash is null");
            apiMessageList = apiDao.selectUserApiMessage(sysUser.getUserId());
            if(apiMessageList == null || apiMessageList.isEmpty()){
                apiMessageList = new ArrayList<>();
            }
        }

        apiMessageList.add(apiMessage);
        System.out.println(apiMessage);
        redisUtil.setHash("api", "apiUserId_" + sysUser.getUserId(), apiMessageList);
        log.info("insert api to redis success");

        return ReturnData.success();
    }

    @Override
    @Transactional
    public ReturnData deleteOwnAPI(Integer apiId, HttpServletRequest request) {
        SysUser sysUser = RequestHolder.getCurrentUser();
        if(sysUser == null){
            throw new MyDataException("用户信息不存在");
        }

        deleteAPI(sysUser.getUserId(), apiId, request);

        return ReturnData.success();
    }

    @Override
    public ReturnData deleteAPI(Integer userId, Integer apiId, HttpServletRequest request) {
        apiDao.deleteAllParam(apiId);
        apiDao.deleteMessage(apiId);
        log.info("Delete API: {} success", apiId);

        Object object = redisUtil.getHash("api", "apiUserId_" + userId);

        if(object != null){
            ArrayList<ApiMessage> apiMessages = (ArrayList) object;

            for(ApiMessage message : apiMessages){
                if(message.getApiId().equals(apiId)){
                    apiMessages.remove(message);
                    break;
                }
            }

            log.info("---> delete from redis success");

            redisUtil.setHash("api", "apiUserId_" + userId, apiMessages);
        }

        return ReturnData.success();
    }

    @Override
    @Transactional
    public ReturnData exchangeAPI(ApiMessage apiMessage, ArrayList<ApiParam> apiParamList, HttpServletRequest request) {
        SysUser sysUser = RequestHolder.getCurrentUser();
        if(sysUser == null){
            throw new MyDataException("用户信息不存在");
        }

        apiMessage.setApiBelongUserId(sysUser.getUserId());
        apiMessage.setApiStatus(ApiStatusEnum.CHECK_PENDING.getValue());
        BeanValidator.check(apiMessage);
        BeanValidator.validateList(apiParamList);

        int line = apiDao.updateMessage(apiMessage);
        log.info("update message success");
        if(line == 0){
            return ReturnData.success();
        }

        apiDao.deleteAllParam(apiMessage.getApiId());
        if(!(apiParamList == null || apiParamList.isEmpty())){
            apiDao.insertParam(apiParamList, apiMessage.getApiId());
            log.info("update params success");

            for(ApiParam param : apiParamList){
                param.setApiId(apiMessage.getApiId());
            }
            apiMessage.setApiParamArrayList(apiParamList);
        }

        Object object = redisUtil.getHash("api", "apiUserId_" + sysUser.getUserId());
        ArrayList<ApiMessage> apiMessages;
        if(object != null){
            apiMessages = (ArrayList) object;
        }else{
            apiMessages = apiDao.selectUserApiMessage(sysUser.getUserId());
        }

        for(ApiMessage message : apiMessages){
            if(message.getApiId().equals(apiMessage.getApiId())){
                apiMessages.remove(message);
                apiMessage.setApiStatus(message.getApiStatus());
                apiMessages.add(apiMessage);
                break;
            }
        }

        redisUtil.setHash("api", "apiUserId_" + sysUser.getUserId(), apiMessages);
        log.info("---> exchange from redis success");

        return ReturnData.success();
    }

    @Override
    public ReturnData searchOwnAllAPIs(HttpServletRequest request) {
        SysUser sysUser = RequestHolder.getCurrentUser();
        if(sysUser == null){
            throw new MyDataException("用户信息不存在");
        }

        ArrayList<ApiMessage> apiMessageList;

        Object object = redisUtil.getHash("api", "apiUserId_" + sysUser.getUserId());
        if(object != null){
            apiMessageList = (ArrayList) object;
        }else{
            log.info("select from database");

            apiMessageList = apiDao.selectUserApiMessage(sysUser.getUserId());

            if(apiMessageList == null || apiMessageList.isEmpty()){
                return ReturnData.fail("该用户没有任何 API 记录");
            }

            apiMessageList = getApiParamList(apiMessageList);
            redisUtil.setHash("api", "apiUserId_" + sysUser.getUserId(), apiMessageList);
        }

        return ReturnData.success(apiMessageList);
    }

    @Override
    public ReturnData searchOwnAPIsByStatus(Integer status, HttpServletRequest request) {
        SysUser sysUser = RequestHolder.getCurrentUser();
        if(sysUser == null){
            throw new MyDataException("用户信息不存在");
        }

        ArrayList<ApiMessage> apiMessageList;
        ArrayList<ApiMessage> messageList;

        Object object = redisUtil.getHash("api", "apiUserId_" + sysUser.getUserId());
        if(object != null){
            messageList = (ArrayList) object;
            apiMessageList = new ArrayList<>();

            for(ApiMessage message : messageList){
                if(message.getApiStatus().equals(status)){
                    apiMessageList.add(message);
                }
            }
        }else{
            log.info("select from database");

            apiMessageList = apiDao.selectUserApiMessageByStatus(sysUser.getUserId(), status);

            if(apiMessageList == null || apiMessageList.isEmpty()){
                return ReturnData.fail("该用户没有任何该状态的 API 记录");
            }

            apiMessageList = getApiParamList(apiMessageList);
        }

        return ReturnData.success(apiMessageList);
    }

    @Override
    public ReturnData searchAllAPI(HttpServletRequest request) {
        ArrayList<ApiMessage> apiMessageList;
        Map<String, Object> map = redisUtil.entries("api");

        if(map != null && map.size() != 0){
            apiMessageList = new ArrayList<>();
            for(Map.Entry entry : map.entrySet()){
                ArrayList<ApiMessage> messages = (ArrayList)entry.getValue();
                for(ApiMessage apiMessage: messages){
                    if(apiMessage.getApiStatus().equals(new Integer(0))){
                        apiMessageList.add(apiMessage);
                    }
                }
//                apiMessageList.addAll(messages);
            }
        }else{
            log.info("select from database");

//            apiMessageList = apiDao.selectAllApiMessage();
            apiMessageList = apiDao.selectApiMessageByStatus(0);
            if(apiMessageList == null || apiMessageList.isEmpty()){
                return ReturnData.fail("没有 API 记录");
            }

            apiMessageList = getApiParamList(apiMessageList);

            for(ApiMessage message : apiMessageList){
                Object object = redisUtil.getHash("api", "apiUserId_" + message.getApiBelongUserId());
                ArrayList<ApiMessage> messages;
                if(object != null){
                    messages = (ArrayList) object;
                }else {
                    messages = new ArrayList<>();
                }
                messages.add(message);
                redisUtil.setHash("api", "apiUserId_" + message.getApiBelongUserId(), messages);
            }
        }

        return ReturnData.success(apiMessageList);
    }

    @Override
    public ReturnData searchOwnAPIsByType(String type, HttpServletRequest request) {
        SysUser sysUser = RequestHolder.getCurrentUser();
        if(sysUser == null){
            throw new MyDataException("用户信息不存在");
        }

        ArrayList<ApiMessage> apiMessageList;
        ArrayList<ApiMessage> messageList;

        Object object = redisUtil.getHash("api", "apiUserId_" + sysUser.getUserId());
        if(object != null){
            messageList = (ArrayList) object;
            apiMessageList = new ArrayList<>();

            for(ApiMessage message : messageList){
                if(message.getApiType().equals(type)){
                    apiMessageList.add(message);
                }
            }
        }else{
            log.info("select from database");

            apiMessageList = apiDao.selectUserApiMessageByType(sysUser.getUserId(), type);

            if(apiMessageList == null || apiMessageList.isEmpty()){
                return ReturnData.fail("该用户没有任何该类型的 API 记录");
            }

            apiMessageList = getApiParamList(apiMessageList);
        }

        return ReturnData.success(apiMessageList);
    }

    @Override
    public ReturnData showAllType(HttpServletRequest request) {
        ArrayList<String> types = apiDao.selectApiTypes();
        if(types == null || types.isEmpty()){
            throw new MyDataException("没有 API 分类");
        }
        return ReturnData.success(types);
    }

    private ArrayList<ApiMessage> getApiParamList(ArrayList<ApiMessage> apiMessageList){
        for(ApiMessage apiMessage : apiMessageList){
            ArrayList<ApiParam> apiParamList = apiDao.selectParams(apiMessage.getApiId());
            apiMessage.setApiParamArrayList(apiParamList);
        }
        return apiMessageList;
    }

}
